package com.wlj.security.core.social;

import com.wlj.security.core.properties.WljSecurityProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.encrypt.Encryptors;
import org.springframework.social.UserIdSource;
import org.springframework.social.config.annotation.EnableSocial;
import org.springframework.social.config.annotation.SocialConfigurerAdapter;
import org.springframework.social.connect.ConnectionFactoryLocator;
import org.springframework.social.connect.ConnectionSignUp;
import org.springframework.social.connect.UsersConnectionRepository;
import org.springframework.social.connect.jdbc.JdbcUsersConnectionRepository;
import org.springframework.social.connect.web.ProviderSignInUtils;
import org.springframework.social.security.SpringSocialConfigurer;
import org.springframework.util.Assert;

import javax.sql.DataSource;

@Configuration
@EnableSocial
public class SocialConfig extends SocialConfigurerAdapter {

    @Autowired
    private DataSource dataSource;

    @Autowired
    private WljSecurityProperties wljSecurityProperties;

    /**
     * 自动注册社交用户
     */
    @Autowired(required = false)
    private ConnectionSignUp connectionSignUp;

    @Autowired(required = false)
    private SocialAuthenticationFilterPostProcessor socialAuthenticationFilterPostProcessor;

    //connectionFactoryLocator作用:查找connectionFactory，因为他可能有多个
    @Override
    public UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator connectionFactoryLocator) {
        //对插入数据库的数据encryptors加解密操作，noOpText：不做任何操作
        JdbcUsersConnectionRepository connectionRepository = new JdbcUsersConnectionRepository(dataSource, connectionFactoryLocator, Encryptors.noOpText());
        connectionRepository.setTablePrefix("tb_");
        if(connectionSignUp!=null){
            connectionRepository.setConnectionSignUp(connectionSignUp);
        }
        return connectionRepository;
    }

    @Bean
    public UserIdSource securityContextUserIdSource(){
        return new UserIdSource() {
            @Override
            public String getUserId() {
                SecurityContext context = SecurityContextHolder.getContext();
                Authentication authentication = context.getAuthentication();
                Assert.state(authentication != null, "Unable to get a ConnectionRepository: no user signed in");
                return authentication.getName();
            }
        };
    }


    //配置SocialAuthenticationFilter
    @Bean
    public SpringSocialConfigurer wljSocialSecurityConfig(){
        WljSpringSocialConfigurer configurer = new WljSpringSocialConfigurer(wljSecurityProperties.getSocial().getFilterProcessesUrl());
        //配置注册页地址，当选择社交登录的用户账号不存在则跳转到注册页，配置了connectionSignUp则自动注册
        configurer.signupUrl(wljSecurityProperties.getBrowser().getSignUpUrl());
        //app环境下，设置SocialAuthenticationFilter的successHandler返回access_token
        configurer.setSocialAuthenticationFilterPostProcessor(socialAuthenticationFilterPostProcessor);
        configurer.setUserIdSource(securityContextUserIdSource());
        return configurer;
    }

    //参数中声明connectionFactoryLocator，spring会自动将它实例注入进参数
    @Bean
    public ProviderSignInUtils providerSignInUtils(ConnectionFactoryLocator connectionFactoryLocator){
        return new ProviderSignInUtils(connectionFactoryLocator,getUsersConnectionRepository(connectionFactoryLocator));
    }


    @Override
    public UserIdSource getUserIdSource() {
        return securityContextUserIdSource();
    }
}
